package com.baizhi.config;

import com.baizhi.realm.AuthenRealm;
import com.baizhi.realm.AuthorRealm;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;

/**
 * @Configuration 声明当前类为一个配置类
 */
@Configuration
public class ShiroConfig {

    /**
     * 创建过滤器工厂
     */
    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean(DefaultWebSecurityManager securityManager){
        /**
         * 创建过滤器工厂
         */
        ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean();
        /**
         * 配置拦截规则  setFilterChainDefinitionMap()
         *
         * 参数为map 在Map中配置拦截规则
         * - 哪些页面和url拦截  authc
         * - 哪些页面和url不拦截 anon
         */
        //        配置拦截规则  哪些页面拦截 哪些不拦截  过滤器链
        Map map = new HashMap();
        /**
         * anon 代表匿名可访问 就是不用登录就可以访问
         *
         * authc 代表登录后才能访问
         *
         * 支持通配符*
         *
         * 注意拦截规则 一个一个配置
         * /* authc 注意：不能写成全部拦截 不能写成全部拦截 不能写成全部拦截 不能写成全部拦截
         */
        map.put("/login.jsp","anon");
        map.put("/login/*","anon");
        map.put("/error/*","anon");
        map.put("/login1.jsp","anon");

        map.put("/main.jsp", "authc");
        map.put("/gurn/*", "authc");
        map.put("/menu/*", "authc");
        map.put("/jsp/*", "authc");

        factoryBean.setFilterChainDefinitionMap(map);

        /**
         * 配置安全管理器
         */
        factoryBean.setSecurityManager(securityManager);

        return factoryBean;

    }

    /**
     *  开启shiro aop注解支持
     *  使用代理方式;所以需要开启代码支持;否则@RequiresRoles等注解无法生效
     * @param securityManager
     * @return
     */
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(DefaultWebSecurityManager securityManager){
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
        return authorizationAttributeSourceAdvisor;
    }

    /**
     * 创建安全管理器
     */
    @Bean
    public DefaultWebSecurityManager securityManager(AuthorRealm authorRealm){
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        /**
         * 将自定义Realm给安全管理器
         */
        securityManager.setRealm(authorRealm);
        return securityManager;
    }

    /**
     * 授权Realm
     */
    @Bean
    public AuthorRealm authorRealm(HashedCredentialsMatcher hashedCredentialsMatcher){
        AuthorRealm authorRealm = new AuthorRealm();
//        设置加密规则
        authorRealm.setCredentialsMatcher(hashedCredentialsMatcher);

        return authorRealm;
    }

//    /**
//     * 创建自定义Realm
//     */
//    @Bean
//    public AuthenRealm authenRealm(HashedCredentialsMatcher hashedCredentialsMatcher){
//        AuthenRealm authenRealm = new AuthenRealm();
////        让自定义Realm使用新的加密规则
//        authenRealm.setCredentialsMatcher(hashedCredentialsMatcher);
//        return authenRealm;
//    }


    /**
     * 密码校验规则HashedCredentialsMatcher
     */
    @Bean
    public HashedCredentialsMatcher hashedCredentialsMatcher() {
        HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher();
        //指定加密方式为MD5
        credentialsMatcher.setHashAlgorithmName("MD5");
        //加密次数 散列次数
        credentialsMatcher.setHashIterations(1024);
        credentialsMatcher.setStoredCredentialsHexEncoded(true);
        return credentialsMatcher;
    }
}
